use clap::{command, Parser, ValueEnum};
use sql2doc_core::{SqlConfig, SqlType};

/// 定义命令行参数的结构体
///
/// 这是一个用于解析命令行参数的结构体，使用了`clap`库进行参数解析。
///
/// # 字段
///
/// - `host`: 字符串类型，指定数据库主机名。
/// - `port`: 可选项，无符号16位整数类型，指定数据库端口号。
/// - `user`: 字符串类型，指定数据库用户名。
/// - `password`: 字符串类型，指定数据库密码。
/// - `database`: 字符串类型，指定要连接的数据库名。
/// - `output`: 可选项，字符串类型，指定输出文件的路径。
/// - `type`: 枚举类型`SqlEnum`，指定数据库类型，默认为`SqlEnum::Mysql`。

#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
pub(crate) struct Args {
    #[arg(long)]
    host: String,
    #[arg(long)]
    port: Option<u16>,
    #[arg(short, long)]
    user: String,
    #[arg(short, long)]
    password: String,
    #[arg(short, long)]
    database: String,
    #[arg(short, long)]
    output: Option<String>,
    #[arg(short, long, value_enum,default_value_t = SqlEnum::Mysql)]
    r#type: SqlEnum,
}

/// SQL数据库类型的枚举
///
/// 定义了两种SQL数据库类型：`Mysql` 和 `Mssql`。
///
/// 使用了 `Debug`, `Clone`, `Copy`, `ValueEnum` 和 `Default` trait 的自动派生。
/// 其中 `Default` trait 使得 `Mysql` 成为默认选项。
#[derive(Debug, Clone, Copy, ValueEnum, Default)]
enum SqlEnum {
    /// MySQL 数据库类型
    #[default]
    Mysql,
    /// MSSQL 数据库类型
    Mssql,
}

impl From<SqlEnum> for SqlType {
    fn from(value: SqlEnum) -> Self {
        match value {
            SqlEnum::Mysql => SqlType::Mysql,
            SqlEnum::Mssql => SqlType::Mssql,
        }
    }
}

impl Args {
    /// 将Args结构体转换为SqlConfig结构体
    ///
    /// 根据Args结构体中的数据库类型字段，自动选择默认端口号，并将其他字段复制到SqlConfig结构体中。
    ///
    /// # 返回值
    ///
    /// - `SqlConfig`：转换后的SqlConfig结构体实例
    fn to_sql_config(&self) -> SqlConfig {
        let port = match self.r#type {
            SqlEnum::Mysql => 3306,
            SqlEnum::Mssql => 1433,
        };
        SqlConfig {
            host: self.host.clone(),
            port: self.port.unwrap_or(port),
            user: self.user.clone(),
            password: self.password.clone(),
            database: self.database.clone(),
            output: self.output.clone(),
        }
    }
}
